"""
大麦网App票品搜索和选择模块
处理演出搜索、场次选择、票价选择等功能（移动端版本）
"""

import time
import logging
import re
from typing import List, Dict, Any, Optional, Tuple
from utils.mobile_driver_base import MobileDriverBase
from utils.common_utils import random_sleep, generate_screenshot_filename


class DamaiTicketSelector:
    """大麦网App票品选择处理类"""

    def __init__(self, mobile_driver: MobileDriverBase, config: Dict[str, Any]):
        self.driver = mobile_driver
        self.config = config
        self.logger = logging.getLogger("DamaiTicketSelector")

        # 大麦App相关信息
        self.app_package = config.get("mobile", {}).get("app_package", "cn.damai")

    def search_event(self, event_name: str) -> bool:
        """搜索指定演出"""
        try:
            self.logger.info(f"正在搜索演出: {event_name}")

            # 确保App在前台
            if not self.driver.is_app_running(self.app_package):
                self.driver.start_app(self.app_package)
                time.sleep(3)

            # 查找搜索框或搜索按钮
            search_elements = [
                {"text": "搜索"},
                {"description": "搜索"},
                {"resourceId": "cn.damai:id/search"},
                {"resourceId": "cn.damai:id/search_edit"},
                {"className": "android.widget.EditText", "textContains": "搜索"},
            ]

            search_clicked = False
            for element_info in search_elements:
                if self.driver.click_element(timeout=3, **element_info):
                    self.logger.info("点击搜索入口成功")
                    search_clicked = True
                    break

            if not search_clicked:
                self.logger.error("未找到搜索入口")
                return False

            time.sleep(2)

            # 输入搜索关键词
            search_input_elements = [
                {"resourceId": "cn.damai:id/search_input"},
                {"className": "android.widget.EditText"},
                {"text": "请输入演出名称"},
                {"description": "搜索输入框"},
            ]

            input_success = False
            for element_info in search_input_elements:
                if self.driver.input_text(event_name, **element_info):
                    self.logger.info(f"输入搜索关键词成功: {event_name}")
                    input_success = True
                    break

            if not input_success:
                self.logger.error("输入搜索关键词失败")
                return False

            # 点击搜索按钮或键盘搜索
            search_button_elements = [
                {"text": "搜索"},
                {"description": "搜索按钮"},
                {"resourceId": "cn.damai:id/search_btn"},
            ]

            for element_info in search_button_elements:
                if self.driver.click_element(timeout=2, **element_info):
                    break
            else:
                # 如果没找到搜索按钮，尝试按回车键
                self.driver.press_key("enter")

            # 等待搜索结果加载
            time.sleep(3)
            return True

        except Exception as e:
            self.logger.error(f"搜索演出失败: {e}")
            return False

    def select_event_from_results(self, event_name: str) -> bool:
        """从搜索结果中选择指定演出"""
        try:
            # 等待搜索结果加载
            time.sleep(3)

            # 查找搜索结果项
            result_elements = [
                {
                    "className": "android.widget.TextView",
                    "textContains": event_name[:10],
                },  # 使用部分名称匹配
                {"resourceId": "cn.damai:id/item_title"},
                {"className": "androidx.recyclerview.widget.RecyclerView"},
            ]

            self.logger.info("查找搜索结果中...")

            # 尝试通过文本匹配找到演出
            if self.driver.scroll_to_element(textContains=event_name[:10]):
                if self.driver.click_element(textContains=event_name[:10]):
                    self.logger.info(f"选择演出成功: {event_name}")
                    time.sleep(3)
                    return True

            # 如果精确匹配失败，尝试模糊匹配
            search_results = self.driver.find_elements(
                resourceId="cn.damai:id/item_title"
            )
            if search_results:
                for result in search_results:
                    result_text = self.driver.get_text(
                        resourceId="cn.damai:id/item_title"
                    )
                    if result_text and self._fuzzy_match(event_name, result_text):
                        result.click()
                        self.logger.info(f"模糊匹配选择演出: {result_text}")
                        time.sleep(3)
                        return True

            # 如果仍然没找到，点击第一个结果
            first_result_elements = [
                {"className": "android.view.ViewGroup", "instance": 0},
                {"resourceId": "cn.damai:id/item_layout", "instance": 0},
            ]

            for element_info in first_result_elements:
                if self.driver.click_element(timeout=2, **element_info):
                    self.logger.warning("未找到完全匹配的演出，选择第一个结果")
                    time.sleep(3)
                    return True

            return False

        except Exception as e:
            self.logger.error(f"选择演出失败: {e}")
            return False

    def go_to_event_directly(self, event_url: str) -> bool:
        """直接访问演出页面（通过外部浏览器或内置WebView）"""
        try:
            self.logger.info(f"直接访问演出页面: {event_url}")

            # 由于App无法直接访问URL，这里可能需要通过其他方式
            # 比如通过剪贴板或者外部浏览器
            self.logger.warning("移动端暂不支持直接访问URL，建议使用搜索功能")
            return False

        except Exception as e:
            self.logger.error(f"访问演出页面失败: {e}")
            return False

    def select_session(self, session_index: int = 0) -> bool:
        """选择演出场次"""
        try:
            self.logger.info(f"正在选择场次 (索引: {session_index})")

            # 等待页面加载
            time.sleep(3)

            # 查找场次选择区域
            session_elements = [
                {"textContains": "场次"},
                {"textContains": "时间"},
                {"resourceId": "cn.damai:id/session"},
                {
                    "className": "android.widget.TextView",
                    "textMatches": r".*\d{4}-\d{2}-\d{2}.*",
                },
            ]

            available_sessions = []
            for element_info in session_elements:
                sessions = self.driver.find_elements(**element_info)
                if sessions:
                    available_sessions.extend(sessions)

            if not available_sessions:
                self.logger.warning("未找到场次选择，可能是单场次演出")
                return True

            self.logger.info(f"找到 {len(available_sessions)} 个场次")

            # 选择指定索引的场次
            if session_index < len(available_sessions):
                target_session = available_sessions[session_index]

                # 获取场次信息
                session_info = (
                    self.driver.get_text(**session_elements[0])
                    if session_elements
                    else "未知场次"
                )
                self.logger.info(f"选择场次: {session_info}")

                # 点击场次
                target_session.click()
                random_sleep(1, 2)
                return True
            else:
                self.logger.error(
                    f"场次索引 {session_index} 超出范围 (共 {len(available_sessions)} 个场次)"
                )
                return False

        except Exception as e:
            self.logger.error(f"选择场次失败: {e}")
            return False

    def select_price(self, price_index: int = 0) -> bool:
        """选择票价"""
        try:
            self.logger.info(f"正在选择票价 (索引: {price_index})")

            # 等待票价列表加载
            time.sleep(2)

            # 查找票价选择区域
            price_elements = [
                {"textMatches": r".*￥\d+.*"},  # 匹配包含价格的文本
                {"resourceId": "cn.damai:id/price"},
                {"className": "android.widget.TextView", "textContains": "元"},
            ]

            available_prices = []
            for element_info in price_elements:
                prices = self.driver.find_elements(**element_info)
                if prices:
                    # 过滤掉售罄的票价
                    for price in prices:
                        price_text = self.driver.get_text(**element_info)
                        if price_text and not self._is_price_sold_out_text(price_text):
                            available_prices.append(price)

            if not available_prices:
                self.logger.error("未找到可购买的票价")
                return False

            self.logger.info(f"找到 {len(available_prices)} 个可购买的票价")

            # 选择指定索引的票价
            if price_index < len(available_prices):
                target_price = available_prices[price_index]

                # 获取票价信息
                price_info = "选定价格"
                self.logger.info(f"选择票价: {price_info}")

                # 点击票价
                target_price.click()
                random_sleep(1, 2)
                return True
            else:
                self.logger.error(f"票价索引 {price_index} 超出可选范围")
                # 默认选择第一个可用票价
                if available_prices:
                    self.logger.info("选择第一个可用票价")
                    available_prices[0].click()
                    random_sleep(1, 2)
                    return True
                return False

        except Exception as e:
            self.logger.error(f"选择票价失败: {e}")
            return False

    def select_ticket_quantity(self, quantity: int = 1) -> bool:
        """选择票数"""
        try:
            self.logger.info(f"正在选择票数: {quantity}")

            # 查找票数选择器
            quantity_elements = [
                {"textContains": "数量"},
                {"resourceId": "cn.damai:id/quantity"},
                {"description": "购票数量"},
            ]

            # 查找加减按钮
            plus_button_elements = [
                {"text": "+"},
                {"description": "增加"},
                {"resourceId": "cn.damai:id/plus"},
            ]

            minus_button_elements = [
                {"text": "-"},
                {"description": "减少"},
                {"resourceId": "cn.damai:id/minus"},
            ]

            # 获取当前数量（默认为1）
            current_quantity = 1

            # 计算需要调整的数量
            diff = quantity - current_quantity

            if diff > 0:
                # 需要增加
                for _ in range(diff):
                    found = False
                    for element_info in plus_button_elements:
                        if self.driver.click_element(timeout=1, **element_info):
                            found = True
                            random_sleep(0.3, 0.5)
                            break
                    if not found:
                        break
            elif diff < 0:
                # 需要减少
                for _ in range(-diff):
                    found = False
                    for element_info in minus_button_elements:
                        if self.driver.click_element(timeout=1, **element_info):
                            found = True
                            random_sleep(0.3, 0.5)
                            break
                    if not found:
                        break

            self.logger.info(f"票数选择完成")
            return True

        except Exception as e:
            self.logger.error(f"选择票数失败: {e}")
            return True  # 即使失败也继续流程，使用默认数量

    def click_buy_now(self) -> bool:
        """点击立即购买按钮"""
        try:
            self.logger.info("正在点击立即购买")

            # 查找立即购买按钮
            buy_button_elements = [
                {"text": "立即购买"},
                {"text": "立即抢购"},
                {"text": "立即预订"},
                {"text": "马上抢"},
                {"textContains": "购买"},
                {"textContains": "抢购"},
                {"resourceId": "cn.damai:id/buy_btn"},
                {"className": "android.widget.Button", "textContains": "立即"},
            ]

            for element_info in buy_button_elements:
                if self.driver.click_element(timeout=2, **element_info):
                    self.logger.info("成功点击立即购买按钮")
                    time.sleep(3)
                    return True

            self.logger.error("未找到可点击的购买按钮")
            self.driver.screenshot(generate_screenshot_filename())
            return False

        except Exception as e:
            self.logger.error(f"点击购买按钮失败: {e}")
            return False

    def _fuzzy_match(self, target: str, text: str, threshold: float = 0.6) -> bool:
        """模糊匹配演出名称"""
        # 移除标点符号和空格
        target_clean = re.sub(r"[^\w\u4e00-\u9fff]", "", target.lower())
        text_clean = re.sub(r"[^\w\u4e00-\u9fff]", "", text.lower())

        # 计算相似度
        if target_clean in text_clean or text_clean in target_clean:
            return True

        # 简单的字符匹配比例
        matches = sum(1 for c in target_clean if c in text_clean)
        similarity = matches / len(target_clean) if target_clean else 0

        return similarity >= threshold

    def _is_price_sold_out_text(self, price_text: str) -> bool:
        """检查票价文本是否包含售罄标识"""
        sold_out_indicators = ["售罄", "sold out", "无票", "暂无库存", "已抢完"]

        price_text_lower = price_text.lower()
        for indicator in sold_out_indicators:
            if indicator in price_text_lower:
                return True

        return False
